package state

type Instruction uint32

const (
	MAXARG_Bx  = 1<<18 - 1
	MAXARG_sBx = MAXARG_Bx >> 1
)

//后6位
func (this Instruction) Opcode() int {
	return int(this & 0x3f) // 0011 1111
}

/**
注意，指令里的次序是 a,c,b 不是 a,b,c
*/
func (this Instruction) ABC() (a, b, c int) {
	a = int(this >> 6 & 0xFF)   //8位
	c = int(this >> 14 & 0x1FF) //9位
	b = int(this >> 23 & 0x1FF) //9位
	return
}

func (this Instruction) ABx() (a, bx int) {
	a = int(this >> 6 & 0xFF) //8位
	bx = int(this >> 14)      // 32-14 = 18 位 无符号
	return
}

func (this Instruction) AsBx() (a, sbx int) {
	a, bx := this.ABx()
	return a, bx - MAXARG_sBx //8 位，18位 有符号
}

func (this Instruction) Ax() int {
	return int(this >> 6)
}

func (this Instruction) OpName() string {
	return opcodes[this.Opcode()].name
}

func (this Instruction) OpMode() byte {
	return opcodes[this.Opcode()].opMode
}

func (this Instruction) BMode() byte {
	return opcodes[this.Opcode()].argBMode
}

func (this Instruction) CMode() byte {
	return opcodes[this.Opcode()].argCMode
}

func (this Instruction) Execute(vm LuaVM) {
	action := opcodes[this.Opcode()].action
	if action != nil {
		action(this, vm)
	} else {
		panic("instruction exec error ," + opcodes[this.Opcode()].name)
	}
}
